home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!cs.utexas.edu!sun-barr!newstop!sun!Central
- From: sunpeaks!auto-trol!marbru@Central (Martin Brunecky)
- Newsgroups: comp.sources.x
- Subject: v06i039: WsXc - Poor man's UIL, Part01/01
- Message-ID: <133252@sun.Eng.Sun.COM>
- Date: 21 Mar 90 10:29:34 GMT
- Sender: news@sun.Eng.Sun.COM
- Lines: 1613
- Approved: argv@sun.com
-
- Submitted-by: sunpeaks!auto-trol!marbru@Central (Martin Brunecky)
- Posting-number: Volume 6, Issue 39
- Archive-name: wsxc/part01
-
- WsXc - POOR MAN'S UIL
-
- This posting contains WsXc, an Xt Intrinsic extension alowing to
- specify the entire user interface within X resource database. A
- HelloWorld example using Motif widgets is included. It is provided
- on as-is basis, without any support or waranties, to gain feedback
- about this approach of user interface definition.
-
- CONTENTS:
-
- o README Basic description of WsXc facility
-
- This is neither a tutorial, nor a reference manual.For more details
- about individual functions, plese refer to the source - it contains
- detailed description of each function. I am sorry I can't provide
- man pages nor Makefile, I just don't know how.
-
- The following files contain the code, based on R3 Xt Intrinsics,
- tested on SPARC, Ultrix/RISC and VAX/VMS. I assume compatibility
- with R4, even though it has not been tested.
-
- o WsCreateXrm.h defines available public functions
- o WsCreateXrmFunc.c widget tree creation and control
- o WsCvtStrToCallback.c string to callback resource convertor
-
- The following is a demo application, using the code listed above,
- and Motif (1.0). You can modify the code to use your favorite
- widget set, and play with application resource files.
-
- o HelloWorld.c sample application
- o HelloWorldBasic basic X resource file, move to ~/HelloWorld
- o HelloWorldMore an expanded X resource file
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README WsCreateXrm.h WsCreateXrmFunc.c
- # WsCvtStrToCallback.c HelloWorld.c HelloWorld_Basic HelloWorld_More
- # Wrapped by marbru@auto-trol on Fri Mar 16 19:31:21 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(9584 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- X UIL or NOT to UIL ?
- X
- X A few weeks ago, comp.windows.x carried a discussion of the
- X advantages and disadvantages of UIL. Some people suggested that UIL
- X is essentially useless, that the X resource database is enough,
- X while others have pointed out that there are things you cannot do
- X with the database alone, such as definition of a widget tree,
- X callbacks, compound strings etc.
- X
- X Prompted by this discussion, I have put together some code which, in
- X my belief, extends the the X Resource Database so that an ENTIRE
- X USER INTERFACE can be defined (and customized) within the database.
- X This avoidins the need for multiple sources of user interface
- X definition by replacing UIL. I am posting an overview of this "POOR
- X MAN'S UIL" here to get some feedback.
- X
- X To start, let me present a simple example of an application-class X
- X resource file for a Motif based HelloWorld:
- X
- X #
- X # shell - an application shell, containing RowColumn organizer
- X #
- X HelloWorld.managed.child_0: box,xmRowColumn
- X #
- X # box - the main container, contains label and button
- X #
- X Helloworld.box.spacing: 8
- X HelloWorld.box.managed.child_0: label,xmLabel
- X HelloWorld.box.managed.child_1: button,xmPushButton
- X #
- X # label
- X #
- X HelloWorld.box.label.labelString: Hello, WORLD !
- X #
- X # button
- X #
- X HelloWorld.box.button.labelString: Push ME
- X HelloWorld.box.button.activateCallback: push(Push again to EXIT)
- X #
- X
- X Except for the top-level shell creation, there is NO widget creation
- X code in my HelloWorld. The entire widget tree definition is shown
- X above. For any widget, I can specify any number of children with
- X all their resources, and all recursively. Callbacks are specified
- X in a similar way, by passing a string argument as call data. Note
- X the example is a starting point: It does NOT show all the
- X functionality such as deffered subtree creation, manage/unmanage
- X callbacks, etc...
- X
- X
- X APPLICATION CODE IMPACT
- X
- X A runtime interpreter must be able to translate X resource database
- X strings into widget classes (or widget creation routines), and
- X callbacks. Even though some systems (VMS for example) allow dynamic
- X binding, the current implementation uses registration routines:
- X
- X WsRegisterObjectClass ( app, "xmlabel", xmLabel );
- X WsRegisterObjectClass ( app, "xmpushbutton", xmPushButton );
- X WsRegisterConstructor ( app, "xmRowColumn", XmCreateRowColumn );
- X
- X WsRegisterCallback ( app, "push", pushCB, NULL );
- X
- X In environments supporting shareable images, all toolkit classes and
- X constructors may be registered during toolkit initialization.
- X
- X To initiate creation of the widget tree from the definitions stored
- X in the X resource database, an application must (either directly, or
- X by means of a callback) invoke the routine:
- X
- X WsCreateXrmChildren ( widget );
- X
- X
- X WIDGET TREE CREATION MECHANISM
- X
- X The WsCreateXrmChildren routine scans the X resource database for
- X widget subresources in the following format:
- X
- X path...widget.[un]managed.child_n: name,class[,nonrecursive]
- X
- X For each such subresource, the routine creates a child as specified
- X by the name and object class (or the creation routine -
- X constructor). Creation recursively descends the widget tree, unless
- X stopped by a non-composite widget/object or the "nonrecursive"
- X option. The latter may be used to defer sub-tree creation, using a
- X callback which invokes WsCreateXrmChildren (for example,
- X WsCreateXrmChildrenCB).
- X
- X When a child is created, WsCreateXrmChildren checks the resource
- X database for xrmCreateCallback resource for the child, and executes
- X such callbacks if present. This mechanism allows the delivery of
- X child's widget ID to other, already existing widgets (such as a
- X Motif defaultButton resource in dialog boxes).
- X
- X
- X CALLBACK STRING CONVERSION
- X
- X A string to callback converter is provided with the package. The
- X converter builds an XtCallbackList using registered callback names.
- X Any callback on the list may have an optional string argument. A
- X pointer to the string is used as callback client data. If no
- X argument (string) is provided, the default client data value
- X provided at registration time is used. The callback resource
- X specification in the X resource database has the following format:
- X
- X path...widget.callbackName: name[(args)][,name[(args)]]...
- X
- X where name is the callback name assigned by WsRegisterCallback, and
- X args presents an arbitrary string.
- X
- X
- X WIDGET TREE CONTROL CALLBACKS
- X
- X The package provides basic callbacks for widget tree control. The
- X callbacks take a (list of) widget names as "client data". The
- X widget name is qualified according to Xrm rules: box.label. The
- X following is list of the provided callbacks:
- X
- X o CreateXrmChildrenCB ( widgetName, widgetname, ... )
- X creates children of the named widgets as specified in the X
- X resource database
- X
- X o ManageNamedChildrenCB ( widgetName, widgetName, ... )
- X manages a (list of) named widget(s)
- X
- X o UnmanageNamedChildrenCB ( widgetName, widgetName, ... )
- X unmanages a (list of) named widget(s).
- X
- X o SetWidgetResourceCB ( resourceName, widgetname, ... )
- X sets the specified resource in a (list of) named widget(s) to
- X the widget id of the widget invoking the callback.
- X
- X Consider the callbacks above as a starting point. More callbacks
- X can be provided to control popup/popdown, to load additional
- X resource files and much more.
- X
- X
- X COMPARISON WITH UIL
- X
- X The X resource database user interface definition, here (for lack of
- X better names) referred to as WsXc, performs essentialy the same
- X function as UIL. A complete comparison with UIL can not be done
- X without additional input. Here I try only to mention several
- X important differences between UIL and WsXc.
- X
- X Implementation:
- X A UIL application uses multiple user interface definition sources
- X (application code, UIL file, compiled UID file and an X resource
- X file). WsXc requires only application code and an X resource file,
- X and the application code would be limited to callback functions.
- X The UIL approach is based on a compiler generating intermediate code
- X which is interpreted by Mrm at runtime. WsXc is purely a runtime
- X interpreter.
- X
- X Performance:
- X Since UIL uses pre-compiled, machine specific data, the widget tree
- X creation could be faster than that for WsXc. However, even UIL
- X widget creation accesses the X resource database for resources NOT
- X explicitly specified by the UIL file. Since MOST resources are
- X usually NOT explictly specified, the overhead depends more on the
- X Xrm database volume, than on the widget creation method used.
- X Preliminary experience with WsXc is favorable. However, final
- X
- X Page 4
- X
- X
- X judgement requires much more experience than is currently available.
- X
- X Extensibility.
- X Adding new widgets to UIL, even with the new Motif WML facility, is
- X not an easy process. Adding new data types (resource representation
- X types) to UIL is sometimes impossible. On the contarry, there is
- X nothing special about adding additional widgets to WsXc. The same
- X method also applies to adding new data types. The only requirement
- X is the addition of a convertor from string to a particular data
- X type.
- X
- X Syntax Checking:
- X The UIL compiler can perform rigorous syntax checking for widget
- X resources, thus assisting in user interface development. WsXc can
- X not catch any syntax errors in resource pathname specification, such
- X resources are simply ignored. However, errors in resource value
- X specification can be caught by the resource converter. In addition,
- X a simple tool that acquires a widget's resource list and performs X
- X resource file syntax checking can be provided.
- X
- X Value Computations:
- X The UIL compiler can compute the geometry of individual widgets
- X using arbitrary arithmetic expressions. Geometry values in the X
- X resource database can not, currently, contain expressions. But,
- X since Xrm uses cpp, a string substitution could be applied. This
- X limitation is a resource converter issue. A more intelligent string
- X to integer converter could evaluate arithmetic expressions,
- X including X resource database value substitution. Besides, geometry
- X configuration should be left to the geometry manager widgets and not
- X hardcoded.
- X
- X Resource Conversions:
- X UIL supports resource conversions such as colors, pixelmaps and
- X compound strings. Many of the conversions are performed at runtime,
- X using resource converters, the same as WsXc. For some resources,
- X such as Compound Strings, UIL compile time conversion provides some
- X runtime savings. In addition, the current string to compound string
- X resource converters are not intelligent enough to allow an unlimited
- X compound string specification in an X resource file.
- X
- END_OF_FILE
- if test 9584 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'WsCreateXrm.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'WsCreateXrm.h'\"
- else
- echo shar: Extracting \"'WsCreateXrm.h'\" \(1153 characters\)
- sed "s/^X//" >'WsCreateXrm.h' <<'END_OF_FILE'
- X/*
- X*******************************************************************************
- X*
- X* SCCS_data: %Z%%M% %I%(%G%)
- X*
- X* Include_name:
- X*
- X* WsCreateXrm.h
- X*
- X* Subsystem_group:
- X*
- X* Window System
- X*
- X* Related_keywords:
- X*
- X* Public Defines
- X*
- X* Include_description:
- X*
- X* Public defines for the Window System widget tree creation from
- X* the Xrm database.
- X*
- X* Include_history:
- X*
- X* mm/dd/yy initials action
- X* -------- -------- -------------------------------------------------------
- X* 03/02/90 marbru created
- X*
- X*******************************************************************************
- X*/
- X#ifndef _WsCreateXrm_h
- X#define _WsCreateXrm_h
- X
- X
- X/* -- Widget constructor registration routine */
- X
- Xextern void WsRegisterObjectClass ();
- Xextern void WsRegisterConstructor ();
- Xextern void WsRegisterCallback ();
- Xextern void WsRegisterXrmCallbacks();
- X
- X/* -- Widget creation routine */
- X
- Xextern void WsCreateXrmChildren ();
- X
- X/* -- Convenience callbacks */
- X
- Xextern void WsCreateXrmChildrenCB();
- Xextern void WsManageNamedChildrenCB();
- Xextern void WsUnmanageNamedChildrenCB();
- Xextern void WsSetWidgetResourceCB();
- X
- X#endif /* _WsCreateXrm_h */
- END_OF_FILE
- if test 1153 -ne `wc -c <'WsCreateXrm.h'`; then
- echo shar: \"'WsCreateXrm.h'\" unpacked with wrong size!
- fi
- # end of 'WsCreateXrm.h'
- fi
- if test -f 'WsCreateXrmFunc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'WsCreateXrmFunc.c'\"
- else
- echo shar: Extracting \"'WsCreateXrmFunc.c'\" \(22340 characters\)
- sed "s/^X//" >'WsCreateXrmFunc.c' <<'END_OF_FILE'
- X/*
- X*******************************************************************************
- X*
- X* SCCS_data: %Z%%M% %I%(%G%)
- X*
- X* Module_name:
- X*
- X* WsCreateXrmFunc.c
- X*
- X* Subsystem_group:
- X*
- X* Window System, Widget tree creation from Xrm database
- X*
- X* Related_keywords:
- X*
- X* Widget, Creation
- X*
- X* Module_description:
- X*
- X* This module contains the functions and convenience callbacks
- X* used to create and manage a widget tree using the Xrm databse.
- X* The Xrm database format used to define widget's children is
- X* as follows:
- X*
- X* toplevel...widget.managed.child_n: name,constructor[,n[onrecursive]]
- X* toplevel...widget.unmanged.child_n: name,constructor[,n[onrecursive]]
- X*
- X* Example:
- X* helloWorld.managed.child_0: box,XmCreateRowColumn
- X* helloWorld.box.managed.child_0: label,XmCreateLabel
- X* helloWorld.box.managed.child_1: button,XmCreatePushButton
- X* helloWorld.box.label.labelString: Hello, World !
- X* helloWorld.box.button.labelString: Bye Bye, World !
- X* helloworld.box.button.activateCallback: push(EXIT)
- X*
- X* Since (for portability reasons) we can not assume runtime binding,
- X* all widget classes or creation routines (constructors) must be
- X* "registered" by the application BEFORE widget tree creation.
- X*
- X* The widget tree creation is performed by the WsCreateXrmChildren()
- X* function, which descends the widget tree recursively until no more
- X* children are found, or widget creation is flagged as "nonrecursive",
- X* or a non-composite widget/object is found.
- X*
- X* Several convenience callbacks are provided here, more will probbably
- X* follow.
- X*
- X* Module_interface_summary:
- X*
- X*
- X* Xt Widget/Object Class Registration Routine:
- X*
- X* WsRegisterObjectClass(
- X* WsAppContext app, - application context
- X* String name, - class name, case insensitive
- X* WidgetClass class ) - class record pointer
- X*
- X*
- X* Xt Widget/Object Contructor Registration Routine:
- X*
- X* WsRegisterConstructor(
- X* WsAppContext app, - application context
- X* String name, - constructor name, case insens.
- X* (*Widget)() const ) - constructor function pointer
- X*
- X*
- X* Standard callback registration routine (all the following callbacks)
- X*
- X* WsRegisterXrmCallbacks (
- X* WsAppContext app ) - application context
- X*
- X* Convenience Callbacks:
- X*
- X* WsCreateXrmChildrenCB () - creates children for named widgets
- X* WsManageNamedChildrenCB () - manages named widgets
- X* WsUnmanageNamedChidrenCB() - unmanages named widgets
- X* WsSetWidgetResourceCB () - sets widget resource in named widgets
- X* WsLoadResourceFileCB () - loads a new database file
- X*
- X*
- X* Module_history:
- X*
- X* mm/dd/yy initials function action
- X* -------- -------- -------- ---------------------------------------------
- X* 02/26/90 MarBru All Created
- X* 02/16/90 MarBru Create.. Limited creation to composite widgets/objects
- X*
- X* Design_notes:
- X
- X* For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
- X* (runtime) binding. But since most UNIX systems lack such capability,
- X* we stick to the concept of "registration" routines.
- X*
- X*******************************************************************************
- X*/
- X/*
- X*******************************************************************************
- X* Include_files.
- X*******************************************************************************
- X*/
- X
- X/* -- Operating system includes */
- X#include <strings.h>
- X#include <ctype.h>
- X
- X/* -- X Window System includes */
- X#include <X11/IntrinsicP.h>
- X#include <X11/StringDefs.h>
- X
- X/* -- Auto-trol Window System includes */
- X
- X/*
- X*******************************************************************************
- X* Private_constant_declarations.
- X*******************************************************************************
- X*/
- X#undef NUL
- X#define NUL '\0'
- X#define MAX_XRMSTRING 1024 /* max length of the Xrm DB string */
- X#define MAX_ERRMSG 1024 /* max length of error message */
- X#define MAX_CHILDREN 1024 /* max number of widget's children */
- X#define ADD_CLASSES 16 /* increment of class cache */
- X
- X#define WsNxrmCreateCallback "xrmCreateCallback"
- X#define WsCXrmCreateCallback "XrmCreateCallback"
- X
- X/*
- X*******************************************************************************
- X* Private_type_declarations.
- X*******************************************************************************
- X Class/constructor cache record contains both class and constructor,
- X one of which must be NULL.
- X*/
- Xtypedef struct /* Class cache record */
- X{
- X XrmQuark quark; /* quarkified callback name */
- X Widget (*constructor)(); /* constructor function ptr */
- X WidgetClass class; /* widget class pointer */
- X} ClCacheRec;
- X
- X/*
- X*******************************************************************************
- X* Private_macro_definitions.
- X*******************************************************************************
- X*/
- X
- X/*
- X*******************************************************************************
- X* Private_data_definitions.
- X*******************************************************************************
- X The following cache/registry of known widget classes and contructors,
- X initially empty, are loaded by the application using "registration"
- X routines.
- X Assuming small numbers of constructors, the sequential search
- X of such cache is (initially) considered acceptable.
- X*/
- X
- X/* -- Named object classes cache, intially empty */
- X
- Xstatic int classes_num = 0;
- Xstatic int classes_max = 0;
- Xstatic ClCacheRec *classes_ptr = NULL;
- X
- X/*
- X*******************************************************************************
- X* Private_function_declarations.
- X*******************************************************************************
- X*/
- X
- X
- X/*
- X -- Names to Widget List
- X******************************************************************************
- X This routine converts a string of comma separated widget names
- X (or widget pathes) into a list of widget id's. Blank space ignored
- X If a NULL string is provided, the widget ID of reference widget
- X is put on the list
- X The widget search starts at the TOP of widget hierarchy (using the
- X top level shell as a reference widget), thus the widget pathname
- X must include all the widget parents (excluding the shell).
- X*/
- Xstatic void NamesToWidgetList ( w, client, widget_list, widget_count )
- XWidget w; /* reference widget */
- Xcaddr_t client; /* callback client data - string of names */
- XWidget *widget_list; /* returned widget list */
- XCardinal *widget_count; /* returned widget count */
- X{
- X char *string = (String)client;
- X char name[MAX_XRMSTRING];
- X register char *s;
- X register char *d;
- X
- X/* -- default case, no string provided, return the calling widget */
- X if (!string)
- X {
- X widget_list[0] = w;
- X *widget_count = 1;
- X return;
- X }
- X
- X/* -- find the reference widget as the toplevel shell */
- X while ( XtParent(w) ) w = XtParent(w);
- X
- X/* -- parse the input string "name.name,name.name,name.name.name" */
- X *widget_count = 0;
- X for ( d = name, s = string; ; s++ )
- X {
- X if ( *s == ',' || *s == NUL )
- X {
- X Widget widget;
- X if ( *s == NUL && d == name ) return;
- X *d = NUL;
- X widget = XtNameToWidget ( w, name );
- X if ( widget )
- X {
- X widget_list[*widget_count] = widget;
- X (*widget_count)++;
- X }
- X else
- X XtStringConversionWarning (name, "Widget");
- X d = name;
- X }
- X else if ( *s > ' ' )
- X {
- X *d++ = *s;
- X }
- X else
- X ;
- X }
- X}
- X/*
- X -- Call Create Callback
- X*******************************************************************************
- X This function calls the CreateCallback defined for the widget in Xrm
- X resource database.
- X Note the xrmCreateCallback "resource" is NOT a true widget resource,
- X there are no instance data associated with it, and only exists in the
- X Xrm resource database, used ONLY at widget creation time.
- X*/
- Xstatic Widget CallCreateCallback ( w )
- XWidget w; /* child's parent */
- X{
- X static XtResource res[] =
- X {
- X { WsNxrmCreateCallback, WsCXrmCreateCallback, XtRCallback,
- X sizeof(XtCallbackList), 0, XtRImmediate, (caddr_t)NULL
- X },
- X };
- X XtCallbackList callback = NULL;
- X
- X XtGetApplicationResources ( w, &callback, res, XtNumber(res), NULL, 0 );
- X
- X /* If there was any callback list defined, invoke all callbacks on list */
- X if ( callback )
- X {
- X XtCallbackRec *cb = callback;
- X for ( cb = callback; cb->callback; cb++ )
- X (*cb->callback) ( w, cb->closure, NULL );
- X
- X }
- X}
- X
- X/*
- X -- Create Database Child
- X*******************************************************************************
- X This function checks the resource database for a presence of widget's
- X subresource in a form:
- X
- X ...widget.type.child_nn: name.constr_name[,n[onrecursive]]
- X
- X where type is either "managed" or "unmanaged".
- X
- X If such a resource is present, the child is created and, if nonrecursive
- X option is NOT present, the CreateDatabseChildren is called for this
- X child causing recursive tree creation. Creation stops if child_0 or
- X two subsequent children are not defined. Creation also stops at any
- X non-composite widget/object. Thus, popup-shells etc. must be created
- X as manager children.
- X
- X*/
- Xstatic Widget CreateDatabaseChild ( w, nn, type )
- XWidget w; /* child's parent */
- Xint nn; /* child # to look for */
- XString type; /* child type: managed or unmanaged */
- X{
- X static XtResource c_resource[] =
- X {
- X { NULL, NULL, XtRString, sizeof(String), 0, XtRImmediate, (caddr_t)NULL },
- X };
- X Boolean recursive;
- X char res_name[20];
- X String string;
- X
- X /* update our resource list to look for type.child_n subresource */
- X sprintf ( res_name, "child_%d", nn );
- X /* toolkit quarkifies resource lists, (flagged by negative offset) */
- X if ( ((int)c_resource[0].resource_offset) < 0 )
- X {
- X XrmQuark qname = XrmStringToQuark(res_name);
- X c_resource[0].resource_name = (String)qname;
- X c_resource[0].resource_class = (String)qname; /* no class used */
- X }
- X else
- X {
- X c_resource[0].resource_name = res_name;
- X c_resource[0].resource_class = res_name; /* no class allowed / used */
- X }
- X XtGetSubresources ( w, &string, type, type, c_resource, 1, NULL, 0 );
- X
- X /* Xrm query returned a string for [un]managed.child_n resource, process */
- X if ( string )
- X {
- X void WsCreateXrmChildren();
- X XrmQuark quark;
- X Widget (*found_const)() = NULL;
- X WidgetClass found_class = NULL;
- X char name [MAX_XRMSTRING];
- X char constr[MAX_XRMSTRING];
- X register char *s;
- X register char *d;
- X register int i;
- X
- X /* extract widget name */
- X for ( d=name, s=string; (*s && *s!=','); )
- X *d++ = *s++;
- X *d = NUL;
- X
- X /* check for missing class/constructor name */
- X if ( *s != ',' )
- X {
- X char msg [MAX_ERRMSG];
- X sprintf ( msg,
- X "Resource db error, missing constructor specifier for %s", name );
- X XtWarning( msg );
- X return (Widget)NULL;
- X }
- X s++;
- X
- X /* extract class/constructor name and force lowercase, no white space */
- X for ( d=constr; (*s && *s!=','); )
- X if (*s > ' ')
- X *d++ = (isupper(*s)) ? tolower(*s++) : *s++;
- X else
- X s++;
- X *d = NUL;
- X
- X /* check for non-recursive option */
- X recursive = ( *s==',' && (s[1]=='n' || s[1]=='N') ) ? FALSE : TRUE;
- X
- X
- X /* try to locate class/constructor in our caches */
- X quark = XrmStringToQuark ( constr );
- X for (i=0; i<classes_num; i++)
- X if ( classes_ptr[i].quark == quark )
- X {
- X found_class = classes_ptr[i].class;
- X found_const = classes_ptr[i].constructor;
- X break;
- X }
- X
- X /* if we'w found a class or constructor, create child, call callback */
- X if (found_class || found_const )
- X {
- X Widget child;
- X if ( found_class )
- X child = XtCreateWidget ( name, found_class, w, NULL, 0 );
- X else
- X child = (*found_const) ( w, name, NULL, 0 );
- X
- X CallCreateCallback ( child );
- X if ( recursive ) WsCreateXrmChildren ( child );
- X return (child);
- X }
- X else
- X {
- X char msg[MAX_ERRMSG];
- X sprintf ( msg,"Cannot create child %s using %s, unknown class/constructor",
- X name, constr );
- X XtWarning( msg );
- X return (Widget)NULL;
- X }
- X }
- X else
- X {
- X return (Widget)NULL;
- X }
- X}
- X
- X/*
- X*******************************************************************************
- X* Public_function_declarations.
- X*******************************************************************************
- X*/
- X/*
- X -- Register Object Class
- X*******************************************************************************
- X This procedure adds object class name to our list of registered
- X classes/constructors. So far very simplistic ... without checking for
- X duplicate entries, no cache hashing scheme....no ties to app_context.
- X*/
- Xvoid WsRegisterObjectClass ( app, name, class )
- XXtAppContext app; /* not used (yet), must be present */
- XString name; /* constructor name, case insensitive */
- XWidgetClass class; /* Xt object class pointer */
- X{
- X char cr_name[MAX_XRMSTRING];
- X register char *s;
- X register char *d;
- X
- X for ( d=cr_name, s=name; *s; s++)
- X *d++ = (isupper(*s)) ? tolower (*s) : *s;
- X *d = '\0';
- X
- X if (classes_num >= classes_max )
- X {
- X classes_max += ADD_CLASSES;
- X classes_ptr = (ClCacheRec*) XtRealloc((char*)classes_ptr,
- X sizeof(ClCacheRec) * classes_max);
- X }
- X classes_ptr[classes_num].quark = XrmStringToQuark ( cr_name );
- X classes_ptr[classes_num].constructor = NULL;
- X classes_ptr[classes_num].class = class;
- X classes_num++;
- X}
- X
- X/*
- X -- Register constructor
- X*******************************************************************************
- X This procedure adds constructor procedure/name to our list of registered
- X classes/constructors. So far very simplistic ... without checking for
- X duplicate entries, no cache hashing scheme....no ties to app_context.
- X
- X Note the constructor is a "standard" widget creation routine
- X Widget WsCreateXyyyZyyy ( parent, name, args, nargs )
- X*/
- Xvoid WsRegisterConstructor ( app, name, constructor )
- XXtAppContext app; /* not used (yet), must be present */
- XString name; /* constructor name, case insensitive */
- XWidget (*constructor) (); /* pointer to a widget creation routine */
- X{
- X char cr_name[MAX_XRMSTRING];
- X register char *s;
- X register char *d;
- X
- X for ( d=cr_name, s=name; *s; s++)
- X *d++ = (isupper(*s)) ? tolower (*s) : *s;
- X *d = '\0';
- X
- X if (classes_num >= classes_max )
- X {
- X classes_max += ADD_CLASSES;
- X classes_ptr = (ClCacheRec*) XtRealloc((char*)classes_ptr,
- X sizeof(ClCacheRec) * classes_max);
- X }
- X classes_ptr[classes_num].quark = XrmStringToQuark ( cr_name );
- X classes_ptr[classes_num].constructor = constructor;
- X classes_ptr[classes_num].class = NULL;
- X classes_num++;
- X}
- X
- X/*
- X -- Create Xrm Database Children
- X*******************************************************************************
- X This routine creates widget children as defined in X reosurce databse.
- X We look for children defintion starting at child 0 (first looking
- X for managed, then unmanaged child). The child lookup terminates if
- X child_0 is not present, or two two subsequent child lookups failed
- X (allowing to continue if one child was defined incorrectly).
- X
- X To reduce the databse search overhead, we only attempt to create
- X children for composite widgets and objects.
- X*/
- Xvoid WsCreateXrmChildren ( w )
- XWidget w;
- X{
- X Widget child;
- X Widget prev;
- X Widget managed[MAX_CHILDREN];
- X register int i,num;
- X
- X/* -- check if the requested widget is a manager ( composite ) */
- X if (! ( XtIsSubclass( w, compositeWidgetClass )
- X || XtIsSubclass( w, compositeObjectClass ) /* not in R3 intrinsics */
- X ) ) return;
- X
- X
- X/* -- look for children definition until we have 2 subsequent misses */
- X child = (Widget) 1;
- X prev = (Widget) 0; /* this makes the child_0 mandatory */
- X
- X for ( i=0, num=0; (prev || child) ;i++)
- X {
- X child = CreateDatabaseChild ( w, i, "managed" );
- X if ( child )
- X managed[num++] = child;
- X else
- X child = CreateDatabaseChild ( w, i, "unmanaged" );
- X prev = child;
- X }
- X XtManageChildren(managed, num );
- X}
- X
- X
- X/*
- X -- Create Xrm Children callback
- X*******************************************************************************
- X
- X For each widget specified by the list of widget names in client data,
- X (or the widget invoking this callback if client data is NULL), this
- X callback creates any children defined in the Xrm database:
- X
- X ....widget.managed.child_0: name,constr_name[,n[onrecursive]]
- X ....widget.unmanaged.child_0: name,constr_name[,n[onrecursive]]
- X
- X If resource above (child_0 - child_nn) exists, the callback creates
- X (and optionally manages) a child using a constructor routine registered
- X under "constr_name".
- X The creation process recursivly follows the widget tree, unless
- X the constructor is specified with the "nonrecursive" option, or
- X a non-composite widget/object is found.
- X
- X The search for "child_n" resource stops if two subsequent children
- X or child_0 are not specified, or their creation fails (error).
- X
- X After all children have been created, the string of widget names
- X is changed to an empty one ("\0"), to prevent duplicate widget
- X creation.
- X
- X*/
- Xvoid WsCreateXrmChildrenCB ( w, client, call )
- XWidget w;
- Xcaddr_t client; /* client data, list of named children */
- Xcaddr_t call; /* call data, not used */
- X{
- X Widget* widget_list[MAX_CHILDREN];
- X Cardinal widget_count;
- X int i;
- X
- X
- X /* for NULL client, we get back "w", for "\0" we get zero widget count */
- X NamesToWidgetList ( w, client, widget_list, &widget_count );
- X
- X for ( i=0; i<widget_count; i++)
- X WsCreateXrmChildren(widget_list[i]);
- X
- X /* prevent repeated invokation by changing string to empty "\0" one */
- X if ( client )
- X *client = NUL;
- X}
- X
- X/*
- X -- Manage named children callback
- X*******************************************************************************
- X This callback translates string passed in as client data into a widget id
- X and manages it. A comma separated list of children can be specified.
- X NULL string pointer defaults widget invoking the callback
- X*/
- Xvoid WsManageNamedChildrenCB ( w, client, call )
- XWidget w;
- Xcaddr_t client; /* client data, list of named children */
- Xcaddr_t call; /* call data, not used */
- X{
- X Widget* widget_list[MAX_CHILDREN];
- X Cardinal widget_count;
- X
- X NamesToWidgetList ( w, client, widget_list, &widget_count );
- X XtManageChildren ( widget_list, widget_count );
- X}
- X
- X
- X/*
- X -- Unmanage named children callback
- X*******************************************************************************
- X This callback translates string passed in as client data into a widget id
- X and manages it. A comma separated list of children can be specified.
- X NULL string pointer defaults widget invoking the callback
- X*/
- Xvoid WsUnmanageNamedChildrenCB ( w, client, call )
- XWidget w;
- Xcaddr_t client; /* client data, list of named children */
- Xcaddr_t call; /* call data, not used */
- X{
- X Widget* widget_list[MAX_CHILDREN];
- X Cardinal widget_count;
- X
- X NamesToWidgetList ( w, client, widget_list, &widget_count );
- X XtUnmanageChildren ( widget_list, widget_count );
- X}
- X
- X
- X/*
- X -- Set Widget Resource Callback
- X*******************************************************************************
- X This callback loads invoking widget into the prescribed resource of the
- X named widget(s).
- X Typically, this callback is used to set the "XmNdefaultButton" resource,
- X and is invoked from button creation callback.
- X
- X The client data argument has a format:
- X
- X resource_name,target_widget_name[,target_widget_name...]
- X*/
- Xvoid WsSetWidgetResourceCB ( w, client, call )
- XWidget w;
- Xcaddr_t client; /* client data, resource name, list of named children */
- Xcaddr_t call; /* call data, not used */
- X{
- X Widget* widget_list[MAX_CHILDREN];
- X Cardinal widget_count;
- X char resource[MAX_XRMSTRING];
- X register char *d,*s;
- X register int i;
- X Arg args[1];
- X
- X for ( d=resource, s=client; (*s && *s!=','); s++ )
- X if (*s > ' ') *d++ = *s;
- X *d = NUL;
- X
- X if (*s == ',' ) s++;
- X if (*s == NUL )
- X {
- X XtWarning("No widget names for WsSetWidgetresourceCB");
- X return;
- X }
- X NamesToWidgetList ( w, s, widget_list, &widget_count );
- X
- X /* set the resource to set */
- X args[0].name = resource;
- X args[0].value = (XtArgVal)w;
- X
- X for (i=0; i<widget_count; i++)
- X XtSetValues ( widget_list[i], args, 1 );
- X}
- X
- X/*
- X -- Load Resource File
- X*******************************************************************************
- X This callbacks loads the specified resource file into application
- X resource database. It allows to load the resources on as-needed
- X basis, reducing the intitial resource load overhead.
- X
- X Two locations are searched for a specified file:
- X
- X XAPP_DEFAULT_PATH
- X XUSER_DEFAULT_PATH (or env.variable "XAPPLRESLANGPATH")
- X
- X Not implemented -- too toolkit dependent ( R3/Motif/R4 ).
- X*/
- Xvoid WsLoadResourceFileCB ( w, client, call )
- XWidget w;
- Xcaddr_t client; /* client data, X resources file name */
- Xcaddr_t call; /* call data, not used */
- X{
- X printf("Sorry, deffered resource load not implemented, file %s\n",call);
- X printf("Merge your file into application class file\n");
- X}
- X
- X/*
- X -- WsRegisterXrmCallbacks
- X*******************************************************************************
- X*/
- Xvoid WsRegisterXrmCallbacks ( app )
- XXtAppContext app;
- X{
- X#define REG( name, cb, cl ) WsRegisterCallback ( app, name, cb, cl )
- X
- X REG("CreateXrmChildrenCB", WsCreateXrmChildrenCB, NULL );
- X REG("ManageNamedChildrenCB", WsManageNamedChildrenCB, NULL );
- X REG("UnmanageNamedChildrenCB", WsUnmanageNamedChildrenCB, NULL );
- X REG("SetWidgetResourceCB", WsSetWidgetResourceCB, NULL );
- X
- X#undef REG
- X}
- END_OF_FILE
- if test 22340 -ne `wc -c <'WsCreateXrmFunc.c'`; then
- echo shar: \"'WsCreateXrmFunc.c'\" unpacked with wrong size!
- fi
- # end of 'WsCreateXrmFunc.c'
- fi
- if test -f 'WsCvtStrToCallback.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'WsCvtStrToCallback.c'\"
- else
- echo shar: Extracting \"'WsCvtStrToCallback.c'\" \(10320 characters\)
- sed "s/^X//" >'WsCvtStrToCallback.c' <<'END_OF_FILE'
- X/*
- X*******************************************************************************
- X*
- X* SCCS_data: %Z%%M% %I%(%G%)
- X*
- X* Module_name:
- X*
- X* WsCvtStrToCallback
- X*
- X* Subsystem_group:
- X*
- X* Window System, Widget Set, Converters
- X*
- X* Related_keywords:
- X*
- X* Converter
- X*
- X* Module_description:
- X*
- X* This module contains the String To Callback X resource converter.
- X*
- X* The converter parses the resource string in the format:
- X*
- X* ...path: name[(args)][,name[(args)]]...
- X*
- X* where: name: specifies the registered callback function name
- X* args: specifies the string passed to a callback as
- X* "client data".
- X*
- X* Multiple callbacks can be specified for a single callback list
- X* resource. Any callbacks must be "registered" by the application
- X* prior converter invocation (.i.e.prior widget creation).
- X* If no "args" string is provided, the default "client data"
- X* specified at callback registration are used.
- X*
- X* Module_interface_summary:
- X*
- X*
- X* Resource converter is invoked indirectly by the toolkit. The
- X* converter is added to the toolkit by widgets calling
- X* WsAddStrToCallbackP() in the widget intialization code.
- X*
- X* To register application callbacks, use:
- X*
- X* WsRegisterCallback (
- X* WsAppContext app, - application context
- X* String name, - register name, case insensitive
- X* Callback callback, - callback function pointer
- X* ClientData closure ) - default client data
- X*
- X* Module_history:
- X*
- X* mm/dd/yy initials function action
- X* -------- -------- -------- ---------------------------------------------
- X* 02/26/90 MarBru All Created
- X*
- X* Design_notes:
- X*
- X* For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
- X* (runtime) binding. But since most UNIX systems lack such capability,
- X* we stick to the concept of "registration" routines.
- X*
- X*******************************************************************************
- X*/
- X/*
- X*******************************************************************************
- X* Include_files.
- X*******************************************************************************
- X*/
- X
- X/* -- Operating system includes */
- X#include <strings.h>
- X#include <ctype.h>
- X
- X/* -- X Window System includes */
- X#include <X11/IntrinsicP.h>
- X#include <X11/StringDefs.h>
- X
- X/* -- Auto-trol Window System includes */
- X
- X/*
- X*******************************************************************************
- X* Private_constant_declarations.
- X*******************************************************************************
- X*/
- X#undef NUL
- X#define NUL '\0'
- X
- X/*
- X*******************************************************************************
- X* Private_type_declarations.
- X*******************************************************************************
- X*/
- X#define MAX_XRMSTRING 1024 /* max length of the DB string */
- X#define MAX_CALLBACKS 64 /* max number of callbacks per list */
- X#define ADD_CALLBACKS 16 /* increment of callback cache size */
- X
- X/*
- X*******************************************************************************
- X* Private_macro_definitions.
- X*******************************************************************************
- X*/
- X
- X/*
- X*******************************************************************************
- X* Private_data_definitions.
- X*******************************************************************************
- X The following cache/registry of known callbacks, initially empty,
- X is loaded by the application using "registration" routines.
- X Assuming small numbers of callbacks, the sequential search
- X of such cache is (initially) considered acceptable.
- X*/
- X
- X/* -- Named callback procedures cache, intially empty */
- X
- Xtypedef struct
- X{
- X XrmQuark quark; /* quarkified callback name */
- X XtCallbackProc callback; /* callback procedure pointer */
- X caddr_t closure; /* default client data */
- X} CBCacheRec;
- X
- X
- X
- Xstatic int callbacks_num = 0;
- Xstatic int callbacks_max = 0;
- Xstatic CBCacheRec *callbacks_ptr = NULL;
- X
- X
- X/*
- X*******************************************************************************
- X* Private_function_declarations.
- X*******************************************************************************
- X*/
- X
- X/*
- X -- Convert String To Callback
- X*******************************************************************************
- X This conversion creates a callback list structure from the X resource
- X database string in format:
- X
- X name(arg),name(arg).....
- X
- X Note "name" is not case sensitive, while "arg" may be - it is passed to
- X a callback as client data as a null terminated string (first level
- X parenthesis stripped off).
- X*/
- Xvoid CvtStringToCallback (args, num_args, fromVal, toVal)
- X
- XXrmValue *args;
- XCardinal *num_args;
- XXrmValue *fromVal;
- XXrmValue *toVal;
- X{
- X typedef struct
- X {
- X char *nsta,*nend; /* callback name start, end */
- X char *asta,*aend; /* argument string start, end */
- X } Segment;
- X
- X static XtCallbackRec *cb;
- X XtCallbackRec callback_list[MAX_CALLBACKS];
- X int callback_num = 0;
- X String string = (char *) fromVal->addr;
- X Segment segs[MAX_CALLBACKS];
- X Segment *seg;
- X register char *s;
- X register int i,ipar;
- X
- X/* -- assume error or undefined input argument */
- X toVal->size = 0;
- X toVal->addr = (caddr_t) NULL;
- X if (s == NULL) return;
- X
- X/* -- parse input string finding segments "name(arg)" comma separated */
- X ipar = 0;
- X seg = segs;
- X seg->nsta = string;
- X seg->nend = seg->asta = seg->aend = (char*)NULL;
- X
- X for ( s=string; *s; s++ )
- X {
- X switch (*s)
- X {
- X case ',': if ( ipar > 0 ) break; /* commas in arguments ignored */
- X if ( seg->nend == NULL ) seg->nend = s-1; /* no argument */
- X seg++; /* start the next segment */
- X seg->nsta = (s[1]) ? s+1 : (char*)NULL;
- X seg->nend = seg->asta = seg->aend = (char*)NULL;
- X break;
- X
- X case '(': if ( ipar++ == 0 ) { seg->nend = s-1; seg->asta = s+1; };
- X break;
- X
- X case ')': if ( --ipar == 0 ) { seg->aend = s-1; };
- X break;
- X deafult: ;
- X }
- X }
- X seg++; /* start the terminating segment */
- X seg->nsta = (char*)NULL;
- X
- X if (ipar)
- X {
- X XtStringConversionWarning (string, "Callback, unbalanced parenthesis");
- X return;
- X }
- X
- X
- X/* -- process individual callback string segments "name(arg)" */
- X for( seg = segs; seg->nsta; seg++)
- X {
- X char cb_name[MAX_XRMSTRING];
- X XtCallbackProc found = (XtCallbackProc)NULL;
- X XrmQuark quark;
- X register char *d;
- X register char *end;
- X
- X /* our callback cache names are case insensitive, no white space */
- X for ( s=seg->nsta, d=cb_name; s<=seg->nend; )
- X if ( *s > ' ')
- X *d++ = (isupper(*s) ) ? tolower (*s++) : *s++;
- X else
- X s++;
- X *d = NUL;
- X
- X /* try to locate callback in our cache of callbacks */
- X quark = XrmStringToQuark (cb_name);
- X for (i=0; i<callbacks_num; i++)
- X if ( callbacks_ptr[i].quark == quark )
- X {
- X register XtCallbackRec *rec = &callback_list[callback_num];
- X rec->callback = found = callbacks_ptr[i].callback;
- X rec->closure = callbacks_ptr[i].closure;
- X break;
- X }
- X
- X /* we have found a registered callback, process arguments */
- X if (found)
- X {
- X register char *arg;
- X register int alen;
- X register XtCallbackRec *rec = &callback_list[callback_num];
- X
- X if ( seg->asta )
- X {
- X alen = (int)seg->aend - (int)seg->asta +1;
- X arg = XtMalloc(alen+1);
- X strncpy ( arg, seg->asta, alen );
- X arg[alen+1] = NUL;
- X rec->closure = (caddr_t)arg;
- X }
- X callback_num++;
- X }
- X else
- X {
- X XtStringConversionWarning (cb_name, "Callback, unknown callback name");
- X }
- X } /* end for seg loop */
- X
- X/* -- terminate the callback list */
- X {
- X register XtCallbackRec *rec = &callback_list[callback_num];
- X rec->callback = NULL;
- X rec->closure = NULL;
- X callback_num++;
- X }
- X
- X/* -- make a permanent copy of the new callback list, and return a pointer */
- X cb = (XtCallbackRec*)XtMalloc( callback_num * sizeof (XtCallbackRec) );
- X memcpy ( (char*)cb, (char*)callback_list,
- X callback_num * sizeof (XtCallbackRec));
- X toVal->size = sizeof (XtCallbackRec*);
- X toVal->addr = (caddr_t)&cb;
- X}
- X
- X/*
- X*******************************************************************************
- X* Public_function_declarations.
- X*******************************************************************************
- X*/
- X
- X/*
- X -- Add String To Callback Convertor
- X*******************************************************************************
- X*/
- X
- Xvoid WsAddStringToCallbackP ()
- X{
- X static Boolean added = FALSE;
- X if ( !added )
- X {
- X XtAddConverter (XtRString,
- X XtRCallback,
- X CvtStringToCallback,
- X (XtConvertArgList)NULL,
- X (Cardinal)0);
- X added = TRUE;
- X }
- X}
- X
- X
- X/*
- X -- Register callback
- X*******************************************************************************
- X This procedure adds callback procedure/name to our list of registered
- X callbacks. So far very simplistic ... without checking for duplicate
- X entries, no cache hashing scheme, no ties to app_context.
- X*/
- Xvoid WsRegisterCallback ( app, name, callback, closure )
- XXtAppContext app; /* not used (yet), must be present */
- XString name; /* callback name, case insensitive */
- XXtCallbackProc callback; /* callback function pointer */
- Xcaddr_t closure; /* default closure (client data) */
- X{
- X char cb_name[MAX_XRMSTRING];
- X register char *s;
- X register char *d;
- X
- X for ( d=cb_name, s=name; *s; s++)
- X *d++ = (isupper(*s)) ? tolower (*s) : *s;
- X *d = '\0';
- X
- X if (callbacks_num >= callbacks_max )
- X {
- X callbacks_max += ADD_CALLBACKS;
- X callbacks_ptr = (CBCacheRec*) XtRealloc((char*)callbacks_ptr,
- X sizeof(CBCacheRec) * callbacks_max);
- X }
- X callbacks_ptr[callbacks_num].quark = XrmStringToQuark ( cb_name );
- X callbacks_ptr[callbacks_num].callback = callback;
- X callbacks_ptr[callbacks_num].closure = closure;
- X callbacks_num++;
- X}
- END_OF_FILE
- if test 10320 -ne `wc -c <'WsCvtStrToCallback.c'`; then
- echo shar: \"'WsCvtStrToCallback.c'\" unpacked with wrong size!
- fi
- # end of 'WsCvtStrToCallback.c'
- fi
- if test -f 'HelloWorld.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'HelloWorld.c'\"
- else
- echo shar: Extracting \"'HelloWorld.c'\" \(3743 characters\)
- sed "s/^X//" >'HelloWorld.c' <<'END_OF_FILE'
- X/*
- X*******************************************************************************
- X* HelloWorld.c
- X*******************************************************************************
- X This program demonstrates usage of the Xrm (X resource management) databse
- X for a widget tree definition and management.
- X There is very little code in this example, since the entire user interface
- X definition is stored in the Xrm database, preferably in the application
- X class resource file: ~/HelloWorld
- X
- X ATTC NOTE: This example does NOT use Ws, since it's intended for use
- X outside Auto-trol.
- X/*
- X*******************************************************************************
- X* Include_files.
- X*******************************************************************************
- X*/
- X
- X#include <Xm/Xm.h> /* Motif public header file */
- X#include <Xm/Label.h> /* Motif label widget */
- X#include <Xm/PushB.h> /* Motif pushbutton widget */
- X#include <Xm/BulletinB.h> /* Motif bulletin board widget */
- X#include <Xm/RowColumn.h> /* Motif row column widget */
- X#include "WsCreateXrm.h" /* Window System Xrm Creation routines */
- X
- X/*
- X*******************************************************************************
- X* Application callback declaration (callbacks should be in a separate file)
- X*******************************************************************************
- X*/
- Xvoid pushCB();
- X
- X/*
- X*******************************************************************************
- X* MAIN function
- X*******************************************************************************
- X*/
- X
- Xmain ( argc, argv )
- Xint argc;
- Xchar **argv;
- X{
- X Widget app_shellW; /* application shell widget */
- X XtAppContext app;
- X
- X/* -- Intialize AWS creating the application shell */
- X app_shellW = XtInitialize ( "helloWorld","HelloWorld",
- X NULL, 0, &argc, argv );
- X app = XtWidgetToApplicationContext(app_shellW);
- X
- X/* -- Register the string to callback converter, used for a pushbutton */
- X WsAddStringToCallbackP();
- X
- X/* -- Register available Widget constructors */
- X WsRegisterConstructor ( app, "xmLabel", XmCreateLabel );
- X WsRegisterConstructor ( app, "xmPushButton", XmCreatePushButton);
- X WsRegisterConstructor ( app, "xmRowColumn", XmCreateRowColumn );
- X WsRegisterObjectClass ( app, "xmBulletinBoard", xmBulletinBoardWidgetClass);
- X
- X/* -- Register available callbacks */
- X WsRegisterXrmCallbacks( app );
- X WsRegisterCallback ( app, "push", pushCB, NULL );
- X
- X
- X/* -- Create children of the toplevel shell defined by the Xrm database */
- X WsCreateXrmChildren ( app_shellW );
- X
- X/* -- Realize the widget tree and enter the main application loop */
- X XtRealizeWidget ( app_shellW );
- X XtMainLoop ( );
- X}
- X/*
- X*******************************************************************************
- X Application callbacks (should be in a separate file)
- X*******************************************************************************
- X*/
- X/*
- X -- Push callback
- X*******************************************************************************
- X This callback is a state machine; the first invocation loads the text
- X specified as client data into XmNlabelString resource of invoking widget;
- X the next invocation exits the application.
- X*/
- Xvoid pushCB ( w, client, call )
- XWidget w;
- Xcaddr_t client;
- Xcaddr_t call;
- X{
- X static Boolean first = TRUE;
- X
- X if ( first )
- X {
- X static Arg setargs[] = { XmNlabelString, NULL };
- X String text = ( client ) ? (String) client : "No text in Xrdb" ;
- X
- X setargs[0].value = (XtArgVal)XmStringCreateLtoR(text,XmSTRING_DEFAULT_CHARSET);
- X WsSetResources ( w, setargs, 1);
- X first = FALSE;
- X }
- X else
- X {
- X exit();
- X }
- X}
- END_OF_FILE
- if test 3743 -ne `wc -c <'HelloWorld.c'`; then
- echo shar: \"'HelloWorld.c'\" unpacked with wrong size!
- fi
- # end of 'HelloWorld.c'
- fi
- if test -f 'HelloWorld_Basic' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'HelloWorld_Basic'\"
- else
- echo shar: Extracting \"'HelloWorld_Basic'\" \(851 characters\)
- sed "s/^X//" >'HelloWorld_Basic' <<'END_OF_FILE'
- X# HelloWorld - global resources
- X#
- X*fontList: -*-Helvetica-Medium-R-Normal--14*
- X#
- X# shell
- X#
- XHelloWorld.managed.child_0: box,xmRowColumn
- X#
- X# box - the main container
- X#
- XHelloWorld.box.spacing: 2
- XHelloWorld.box.background: red
- XHelloWorld.box.marginWidth: 4
- XHelloWorld.box.marginHeight: 4
- XHelloWorld.box.entryAlignment: alignment_center
- XHelloWorld.box.managed.child_0: label,xmlabel
- XHelloWorld.box.managed.child_1: button,xmpushbutton
- X#
- X# label
- X#
- XHelloWorld.box.label.background: white
- XHelloWorld.box.label.foreground: blue
- XHelloWorld.box.label.labelString: Hello, WORLD !
- X#
- X# button
- X#
- XHelloWorld.box.button.background: lightBlue
- XHelloWorld.box.button.foreground: white
- XHelloWorld.box.button.location: center
- XHelloWorld.box.button.labelString: Push ME
- XHelloWorld.box.button.activateCallback: push(Push to EXIT)
- X#
- END_OF_FILE
- if test 851 -ne `wc -c <'HelloWorld_Basic'`; then
- echo shar: \"'HelloWorld_Basic'\" unpacked with wrong size!
- fi
- # end of 'HelloWorld_Basic'
- fi
- if test -f 'HelloWorld_More' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'HelloWorld_More'\"
- else
- echo shar: Extracting \"'HelloWorld_More'\" \(2171 characters\)
- sed "s/^X//" >'HelloWorld_More' <<'END_OF_FILE'
- X#
- X# HelloWorld
- X# box main container
- X# lbl1 headline label - hello world
- X# box1 bulletin board for default button testing
- X# btn1 default button
- X# btn2 button controlling lbl2
- X# btn3 button controlling lbl2
- X# lbl2 footnote
- X#
- X# global resources
- X#
- X*fontList: -*-Helvetica-Medium-R-Normal--14*
- X#
- X# shell
- X#
- XHelloworld.input: true
- XHelloWorld.managed.child_0: box,xmRowColumn
- X#
- X# box - the main container
- X#
- XHelloWorld.box.layout: column
- XHelloWorld.box.spacing: 8
- XHelloWorld.box.background: red
- XHelloWorld.box.marginWidth: 0
- XHelloWorld.box.marginHeight: 0
- XHelloWorld.box.entryAlignment: alignment_center
- XHelloWorld.box.managed.child_0: lbl1,xmLabel
- XHelloWorld.box.managed.child_1: box1,xmBulletinBoard
- XHelloWorld.box.managed.child_2: btn2,xmPushButton
- XHelloWorld.box.managed.child_3: btn3,xmPushButton
- XHelloWorld.box.managed.child_4: lbl2,xmLabel
- X#
- X# lbl1
- X#
- XHelloWorld.box.lbl1.background: white
- XHelloWorld.box.lbl1.foreground: blue
- XHelloWorld.box.lbl1.labelString: Hello, WORLD !
- X#
- X# box1
- X#
- XHelloWorld.box.box1.marginWidth: 8
- XHelloWorld.box.box1.marginHeight: 8
- XHelloWorld.box.box1.managed.child_0: btn1,xmPushButton
- X#
- X# btn1
- X#
- XHelloWorld.box.box1.btn1.labelString: Push ME
- XHelloWorld.box.box1.btn1.background: lightBlue
- XHelloWorld.box.box1.btn1.foreground: red
- XHelloWorld.box.box1.btn1.showAsDefault: 2
- XHelloWorld.box.box1.btn1.xrmCreateCallback: SetWidgetResourceCB(defaultButton,box.box1)
- XHelloWorld.box.box1.btn1.activateCallback: push(Push to EXIT !)
- X#
- X# btn2
- X#
- XHelloWorld.box.btn2.background: lightBlue
- XHelloWorld.box.btn2.foreground: blue
- XHelloWorld.box.btn2.labelString: Remove Footnote
- XHelloWorld.box.btn2.activateCallback: UnmanageNamedChildrenCB(box.lbl2)
- X#
- X# btn3
- X#
- XHelloWorld.box.btn3.background: lightBlue
- XHelloWorld.box.btn3.foreground: blue
- XHelloWorld.box.btn3.labelString: Add Footnote
- XHelloWorld.box.btn3.activateCallback: ManageNamedChildrenCB(box.lbl2)
- X#
- X# lbl2
- X#
- XHelloWorld.box.lbl2.background: white
- XHelloWorld.box.lbl2.foreground: blue
- XHelloWorld.box.lbl2.labelString: Ain't it WONDERFULL ?
- X#
- END_OF_FILE
- if test 2171 -ne `wc -c <'HelloWorld_More'`; then
- echo shar: \"'HelloWorld_More'\" unpacked with wrong size!
- fi
- # end of 'HelloWorld_More'
- fi
- echo shar: End of shell archive.
- exit 0
-
- dan
- -----------------------------------------------------------
- O'Reilly && Associates
- argv@sun.com / argv@ora.com
- 632 Petaluma Ave, Sebastopol, CA 95472
- 800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104
- Opinions expressed reflect those of the author only.
-